//////////////////////////////////////////////////////////////////////////
#pragma once


//////////////////////////////////////////////////////////////////////////
#include "Math/Math.hpp"


namespace Math
{
	class Point3f
	{
	public:
		// Element index's.
		static const size_t						kXIndex		=	0;
		static const size_t						kYIndex		=	1;
		static const size_t						kZIndex		=	2;

		// Basic type information.
		typedef Point3f							ValueType_t;
		typedef const Point3f&					ParamType_t;

		// Construction.
		Point3f();
		Point3f( const Point3f& rhs );
		Point3f( float x, float y, float z );

		// Accessors.
		float						X() const;
		float						Y() const;
		float						Z() const;
		void						X( float x );
		void						Y( float y );
		void						Z( float z );

		// Array accessors.
		float						operator ()( size_t idx ) const;
		void						operator ()( size_t idx, float v );

		// Assignments.
		void						Set( float x, float y, float z );
		const Point3f&				operator =( const Point3f& rhs );

		// Operator overloads.
		Point3f						operator -() const;
		Vector3f					operator -( const Point3f& rhs ) const;
		Point3f						operator +( const Point3f& rhs ) const;
		void						operator -=( const Point3f& rhs );
		void						operator +=( const Point3f& rhs );

		// Member functions.
		bool						IsValid() const;

		// Static initializers.
		static const Point3f		Zero();
		static const Point3f		XAxis();
		static const Point3f		YAxis();
		static const Point3f		ZAxis();

	private:
		// Implementation data.
		float						mX;
		float						mY;
		float						mZ;
	};


	//////////////////////////////////////////////////////////////////////////
	// Helper functions.
	inline float					Dot( const Point3f& lhs, const Point3f& rhs );
	inline Point3f					Multiply( const Point3f& lhs, const Point3f& rhs );
}


// Include the implementations.
#include "Detail/Point3f_Impl.hpp"
